/*
 * randomtestcard.c
 * Assignment 4: Random tester
 *  Created on: Feb 6, 2014
 *      Author: Charles Clampitt
 */


#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "rngs.h"
#include <math.h>

#define DEBUG 0

// Prototype
int stewardTest(int player, int card, int handPos, int choice1, int choice2, int choice3, struct gameState *state);

/*
 * This test will take the current playe, handPos, and passed randomly the choice of 1-3 and the game state.
 * At some point I may want to make this match the cardeffect method signature a bit better by adding the
 * bonus parameter as well so I can use this as a template for all card tests.
 */
int stewardTest(int player, int card, int handPos, int choice1, int choice2, int choice3, struct gameState *state)
{


  int numerrors = 0;
  int testcount;

  struct gameState gameStateTest;
  memcpy (&gameStateTest, state, sizeof(struct gameState));

  // Get our test count for the player and hand
	 testcount = state->handCount[0];
	// printf("Handcount = %d\n", testcount);

  // This will be the expected that we compare after the below test and it should equal result
  //expected = cardEffect(card, choice1, choice2, choice3, state, handPos, 0);
  //cardEffect(card, choice1, 0, 0, state, handPos, 0);

  if (choice1 == 1)
       {
	  // draw 2 discard 1 = +1  -- This is hand count
	  cardEffect(card, 1, 0, 0, state, handPos, 0);
	 	               if (state->handCount[0] != testcount + 1)
	 	               {
	 	                	  numerrors = numerrors + 1;//did not match so add to error count
	 	             	  printf("Our current hand count is %d when it should be %d\n", state->handCount[0], testcount+1);
	 	               }

          }
        else if (choice1 == 2)
          {
            //+2 coins
        	 cardEffect(card, 2, 0, 0, state, handPos, 0);
            //gameStateTest.coins = gameStateTest.coins + 2;
        	if(gameStateTest.coins +2 != (state->coins ))
        	{
        		  numerrors = numerrors + 1;//did not match so add to error count
        	         	  printf("Our number of coins did not match we have %d when it should be %d\n", gameStateTest.coins+2, state->coins+2);
        	}
          }
        else
          {
            //trash 2 cards in hand
        	int bob = state->hand[0][3];
           	int sue = state->hand[0][5];

        	//printf("bob = %d\n", bob);
          //  	printf("sue = %d\n", sue);

        	 cardEffect(card, 3, 0, 0, state, handPos, 1); // note we have to set trash flag
        	   if (state->handCount[0] != testcount - 3)
        		{
        	    numerrors = numerrors + 1;//did not match so add to error count
        		  printf("Our current hand count after trash is %d when it should be %d\n", state->handCount[0], testcount-3);
        		 	               }
        	                bob = state->hand[0][3] = -1;
        	              	 sue = state->hand[0][5] = -1;

          }

        //discard card from hand
        discardCard(handPos, player, &gameStateTest, 0);


  // Return 0 if no errors otherwise return numerrors count
  return numerrors;
}



int main(){

	int x,y,z;
	int testNums = 5000; // number of tests to run
	int players;
	int maxPlayers=4; // max number of players
	int numErrors = 0; // counter for number of errors found
	int handPos, card, choice1, choice2, choice3;
	struct gameState gsPre;// game state pre-test

  printf("Testing stewardTest start\n");

// generate seed
  SelectStream(2);
  PutSeed(3);

  for (x = 0; x < testNums; x++) {
    for (y = 0; y < sizeof(struct gameState); y++) {
      ((char*)&gsPre)[y] = floor(Random() * 256);
    }

    players = (int)(Random() * maxPlayers);
    gsPre.handCount[players] = floor(Random() * MAX_HAND);
    gsPre.deckCount[players] = floor(Random() * MAX_DECK);
    gsPre.discardCount[players] = floor(Random() * MAX_DECK);
    gsPre.numBuys = 1;
    gsPre.numActions = 1;
    gsPre.playedCardCount = 0;
    gsPre.whoseTurn = players;
    gsPre.outpostPlayed = 0;
    gsPre.phase = 0;



    for(z=0;z<gsPre.handCount[players];z++){

        gsPre.hand[players][z] = 5;

      }

    for(z=0;z<gsPre.deckCount[players];z++){

      gsPre.deck[players][z] = (int)(Random() * MAX_HAND);

    }

    for(z=0;z<gsPre.discardCount[players];z++){

      gsPre.discard[players][z] = (int)(Random() * MAX_HAND);

    }


    // Assign randomly supplyCount

    for (z = 0; z <= treasure_map; z++) {

      gsPre.supplyCount[z] = (int)(Random() * 52); //most possible cards should be 52, (60-2*number of players)

    }

    // Setup the options to go to the
    card = steward;

    int opt = floor((Random() * 3)) + 1;
    if (opt == 1)
    {
    	  choice1 = 1;
    	  choice2 = 0;
    	  choice3 = 0;
    }
    if (opt == 2)
        {
        	  choice1 = 2;
        	  choice2 = 0;
        	  choice3 = 0;
        }
    if (opt == 3)
        {
        	  choice1 = 3;
        	  choice2 = 0;
        	  choice3 = 0;
        }

    handPos = (int)(Random() * gsPre.handCount[players]);


    numErrors += stewardTest(players, card, handPos, choice1, 0, 0, &gsPre);


  }

  printf ("ALL TESTS RUN OK!\n");



  if (numErrors == 0){ printf("There were no errors found in %d tests!\n", testNums);  }
  else if(numErrors > 0){ printf("There were %d errors in %d tests run!\n",numErrors, testNums); }
  else{ printf("The error count was not 0 or more so your test puked! \n");  }

  return 0;

}

